package com.yh.base.common;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import javax.servlet.ServletContext;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.yh.base.service.BaseService;
import com.yh.base.util.ObjectUtil;


/**
 * 
 * 全局配置缓存
 * 
 * @author  严华
 * @version  [版本号, 2012-11-4]
 * @see  [相关类/方法]
 * @since  [产品/模块版本]
 */
public class GlobalConfig {

    private final static Log log = LogFactory.getLog(GlobalConfig.class);
    
	@SuppressWarnings("rawtypes")
    private static Map dataMap = new HashMap();

	private static GlobalConfig globalConfig = new GlobalConfig();
	private static ServletContext servletContext;
	
	private static BaseService baseService;

	private GlobalConfig() {
	}

	public static GlobalConfig newInstance() {
		return globalConfig;
	}

	@SuppressWarnings("rawtypes")
    public List getDataListMapByTagCode(String tagCode) {
		if (dataMap == null || dataMap.isEmpty()) {
			// 重新初始化一下dataMap
			reInitDataMap();
		}

		return (List)dataMap.get(tagCode);
	}

	/**
	 * 
	 * 根据tagCode获取数据信息，以 #_#分隔
	 *
	 * @author  严华
	 * @param tagCode
	 * @return [参数说明]
	 * 
	 * @return List<String> [返回类型说明]
	 * @exception throws [异常类型] [异常说明]
	 */
	@SuppressWarnings("unchecked")
    public List<String> getDataListTagCode(String tagCode) {
		List<String> resultList = new ArrayList<String>();
		List<Map<String, String>> list = this.getDataListMapByTagCode(tagCode);
		for (Map<String, String> item : list) {
			//每个map其实只有一条记录
			String key = item.get("KEY");
			String value = item.get("VALUE");
			String msg = key + "#_#" + value;
			resultList.add(msg);
		}
		
		return resultList;
	}

	/**
	 * 系统启动时初始化系统参数及缓存公共资源
	 * 从数据配置中获取配置的tagCode信息，并执行对应的sql语句，得到需要缓存到应用级(applicaiton)的缓存数据
	 *
	 * @author  严华
	 * @param sc
	 * @param resourceStream
	 * @throws Exception [参数说明]
	 * 
	 * @return void [返回类型说明]
	 * @exception throws [异常类型] [异常说明]
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
    public void initDataMap(ServletContext sc, InputStream resourceStream) throws Exception {
		// 些没有用自动注入，因为发现注入不了
		servletContext = sc;
		WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
		baseService = (BaseService) wac.getBean("baseService");
		
		/* 
		 * 这里注意：这里是加载存放在数据库里需要加载到缓存里面的数据， 因最开始没有故先把此处注释掉。
		 * 当需要加载数据库数据到缓存时，参照着更改程序
		 * 
		 * */
		//dataMap = init();
		
		// 初始化appconfig参数
        Properties appConfig = new Properties();
        appConfig.loadFromXML(resourceStream);
        
        Enumeration enumeration = appConfig.propertyNames();
        log.debug("load appConfig.............................");
        while(enumeration.hasMoreElements()) {
            String key = ObjectUtil.toString(enumeration.nextElement());
            String value = appConfig.getProperty(key);
            dataMap.put(key, value);
            log.debug(key + "=======>" + value);
        }

	}

	/**
	 * 
	 * 重新初始化缓存数据
	 *
	 * @author  严华 [参数说明]
	 * 
	 * @return void [返回类型说明]
	 * @exception throws [异常类型] [异常说明]
	 */
	public void reInitDataMap() {
		// 替换时需要关注，不能影响正常使用的，所有应该是先获取数据到临时dataMap中，再赋值替换当前的dataMap
		dataMap = init();
	}

	/**
	 * 
	 * 公共应用级缓存初始化获取获取方法
	 *
	 * @author  严华
	 * @return [参数说明]
	 * 
	 * @return Map [返回类型说明]
	 * @exception throws [异常类型] [异常说明]
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
    private Map init() {
		Map map = new HashMap();
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("param_type_id", Constant.COM_PARAM_TYPE_APPLICATION);
		List<Map<String, String>> dataList = baseService.findList("common.selectComParamInfoList", param);
		for (Map<String, String> item : dataList) {
			String tagCode = item.get("TAG_CODE");
			param.clear();
			param.put("tag_code", tagCode);
			List<Map<String, String>> tagInfoList = baseService.findList("common.selectComTagInfoList", param);
			for (Map<String, String> tagInfo : tagInfoList) {
				param.clear();
				param.put("qry_sql", tagInfo.get("TAG_SQL"));
				List<Map<String, String>> tagInfodataList = baseService.findList("common.selectCommonDataList", param);
				if (tagInfodataList.size() > 0) {
					map.put(tagCode, tagInfodataList);
				}
			}
		}

		// load appconfig.xml
		return map;
	}
	
	public Object get(String key) {
	    return dataMap.get(key);
	}
}
